package com.byit.utils;

import com.alibaba.fastjson.JSONObject;
import com.byit.config.MinioConfig;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * 非对称文件储存工具类
 *
 * @author zjl
 */
@Component
public class MinioUtil {

    @Autowired
    private MinioClient byitMinioClient;

    @Autowired
    private MinioConfig minioConfig;

    /**
     * @param inputStream
     * @param suffix
     * @return
     * @throws Exception
     * @Title: uploadImage
     * @Description:上传图片
     */
    public JSONObject uploadImage(InputStream inputStream, String suffix, String folder) throws Exception {
        return upload(inputStream, suffix, "image/jpeg", folder);
    }

    /**
     * @param inputStream
     * @param suffix
     * @return
     * @throws Exception
     * @Title: uploadVideo
     * @Description:上传视频
     */
    public JSONObject uploadVideo(InputStream inputStream, String suffix, String folder) throws Exception {
        return upload(inputStream, suffix, "video/mp4", folder);
    }


    /**
     * @param inputStream
     * @param suffix
     * @return
     * @throws Exception
     * @Title: uploadVideo
     * @Description:上传文件
     */
    public JSONObject uploadFile(InputStream inputStream, String suffix, String folder) throws Exception {
        return upload(inputStream, suffix, "application/octet-stream", folder);
    }


    /**
     * 上传字符串大文本内容
     *
     * @param str
     * @return
     * @throws Exception
     * @Title: uploadString
     * @Description:描述方法
     */
    public JSONObject uploadString(String str, String folder) throws Exception {
        if (str == null || str.length() == 0) {
            return new JSONObject();
        }
        InputStream inputStream = new ByteArrayInputStream(str.getBytes());
        return upload(inputStream, null, "text/html", folder);
    }

    /**
     * 剪切文件
     *
     * @param url
     * @param destUrl
     * @throws Exception
     */
    public String cutFile(String url, String destUrl) throws Exception {
        String oldurl = url.substring(url.indexOf("/", 1));
        String newurl = destUrl + oldurl.substring(oldurl.indexOf("/", 1) + 1);
        byitMinioClient.copyObject(minioConfig.getBucketName(), oldurl, minioConfig.getBucketName(), newurl);
        delete(url);
        return "/" + minioConfig.getBucketName() + "/" + newurl;
    }

    /**
     * 删除文件
     *
     * @param url 文件相对路径
     * @throws Exception
     */
    public void delete(String url) throws Exception {
        byitMinioClient.removeObject(minioConfig.getBucketName(), url.substring(url.indexOf("/", 1)));
    }

    /**
     * 下载
     *
     * @param response response
     * @param url      minio上的文件相对路径
     * @param fileName 下载后文件的名字
     * @throws Exception
     */
    public void downLoad(final HttpServletResponse response, String url, String fileName) throws Exception {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            inputStream = byitMinioClient.getObject(minioConfig.getBucketName(), url.substring(url.indexOf("/", 1)));
            byte[] buffer = new byte[1024];
            int len;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while ((len = inputStream.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.close();
            byte[] data = bos.toByteArray();
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.reset();
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            response.addHeader("Content-Length", "" + data.length);
            response.setContentType("application/octet-stream;charset=UTF-8");
            outputStream = new BufferedOutputStream(response.getOutputStream());
            outputStream.write(data);
            outputStream.flush();
            response.flushBuffer();
        } catch (Exception e) {
            new Exception();
            e.printStackTrace();
        } finally {
            if (null != inputStream) {
                inputStream.close();
            }
            if (null != outputStream) {
                outputStream.close();
            }
        }
    }

    /**
     * 获取minio服务器文件输入流
     *
     * @param url
     * @return
     * @throws Exception
     */
    public InputStream getInputStream(String url) throws Exception {
        return byitMinioClient.getObject(minioConfig.getBucketName(), url.substring(url.indexOf("/", 1)));

    }

    /**
     * @return
     * @throws Exception
     * @Title: upload
     * @Description:上传主功能
     */
    private JSONObject upload(InputStream inputStream, String suffix, String contentType, String folder) {
        JSONObject map = new JSONObject();
        try {

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
            String ymd = sdf.format(new Date());
            String objectName = folder + ymd + "/" + UUID.randomUUID().toString() + (suffix != null ? suffix : "");

            boolean isExist = byitMinioClient.bucketExists(minioConfig.getBucketName());
            if (!isExist) {
                byitMinioClient.makeBucket(minioConfig.getBucketName());
            }

            byitMinioClient.putObject(minioConfig.getBucketName(), objectName, inputStream, contentType);
            //String url = minioClient.getObjectUrl(minio_bucketName, objectName);

            String url = minioConfig.getSearchMinio() + "/" + minioConfig.getBucketName() + "/" + objectName;
            map.put("flag", "0");
            map.put("msg", "上传成功");
            map.put("url", url);
            map.put("path", "/" + minioConfig.getBucketName() + "/" + objectName);
        } catch (Exception e) {
            e.printStackTrace();
            map.put("flag", "1");
            map.put("msg", "上传失败");
            map.put("url", "");
            map.put("path", "");
        }
        return map;
    }


}
